<?php
/**
 * User: YL
 * Date: 2019/6/10
 */

namespace app\common\model;

use app\common\ConstAttribute;
use app\common\TraitAttribute;
use restful\traits\ParamsHandle;
use think\db\Query;
use think\Model;

class Base extends Model implements ConstAttribute
{
    use TraitAttribute;
    use ParamsHandle;

    const NO_DELETETIME = 0;

    const DEFAULT_FIELD     = true;
    const DEFAULT_OFFSET    = 0;
    const DEFAULT_LIMIT     = 10;
    const DEFAULT_PAGE      = 1;
    const DEFAULT_PAGE_SIZE = 10;

    // 数据缓存时间(1h)
    protected $cacheExpire = 3600;

    /**
     * 获取随机过期时间
     * @return int
     * @throws \Exception
     */
    protected function getRandCacheExpire()
    {
        return $this->cacheExpire + random_int(10, 60);
    }

    /**
     * 获取数组
     * @param Model $data
     * @return mixed
     */
    protected function getArray($data)
    {
        return gettype($data) == 'object' ? $data->toArray() : $data;
    }

    /**
     * 组装查询
     * @param Query $db
     * @param array $params
     * @param string $alias
     * @throws \restful\ResultException
     */
    protected function assemblySelect(Query &$db, array $params, string $alias = '')
    {
        // 排序
        if (! empty($params['sort']) && is_string($params['sort'])) {
            if (! $this->validateFieldIsAllow($db, $params['sort'])) {
                $this->error('不允许的排序字段');
            }
            if (! empty($alias)) {
                $params['sort']  = sprintf('%s.%s', $alias, $params['sort']);
            }
            if (empty($params['order']) || ! is_string($params['order'])) {
                $params['order'] = 'desc';
            }
            $db->order($params['sort'], $params['order']);
        }

        // 根据limit和offset获取
        if ((! empty($params['limit']) || ! empty($params['offset'])) && empty($params['page']) && empty($params['page_size'])) {
            if (empty($params['offset']) || ! is_numeric($params['offset'])) {
                $params['offset'] = static::DEFAULT_OFFSET;
            }
            if (empty($params['limit']) || ! is_numeric($params['limit'])) {
                $params['limit'] = static::DEFAULT_LIMIT;
            }
            $db->limit($params['offset'], $params['limit']);
        }

        // 根据page和page_size获取
        if (empty($params['limit']) && empty($params['offset']) && (! empty($params['page']) || ! empty($params['page_size']))) {
            if (empty($params['page']) || ! is_numeric($params['page'])) {
                $params['page'] = static::DEFAULT_PAGE;
            }
            if (empty($params['page_size']) || ! is_numeric($params['page_size'])) {
                $params['page_size'] = static::DEFAULT_PAGE_SIZE;
            }
            $db->page($params['page'], $params['page_size']);
        }

        // 根据条件过滤
        if (! empty($params['where']) && is_array($params['where'])) {
            $db->where($params['where']);
        }

        // 字段过滤
        if (empty($params['field']) || ! is_string($params['field'])) {
            $params['field'] = static::DEFAULT_FIELD;
        }
        // 如果是排除的话
        if (! empty($params['except'])) {
            $db->withoutField($params['field']);
        } else {
            $db->field($params['field']);
        }
    }

    /**
     * 验证字段是否允许
     * @param Query $db
     * @param string $field
     * @return bool
     */
    private function validateFieldIsAllow(Query $db, string $field)
    {
        return in_array($field, $db->getTableFields());
    }
}